from sw_server import get_sw_app
import os
import win32com.client
import pythoncom
import time


def create_or_use_assembly(sw_app, template_path=None):
    """
    如果已有装配体打开，则使用它；
    否则创建一个新的装配体。
    """
    try:
        # 获取当前活动文档
        active_doc = sw_app.ActiveDoc
        if active_doc is not None:
 
                    return active_doc


    except Exception as e:
        print(f"⚠️ 检查活动文档时出错: {e}")

    # 如果没有打开装配体，创建一个新的
    print("🔧 未检测到打开的装配体，正在创建新的...")
    
    if template_path is None:
        template_path = r"C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2025\templates\gb_assembly.asmdot"

    if not os.path.exists(template_path):
        print(f"⚠️ 模板文件不存在: {template_path}")
        print("尝试使用 NewAssembly 方法...")
        try:
            assembly_doc = sw_app.NewAssembly()
            if assembly_doc:
                print("✅ 使用 NewAssembly 成功创建装配体")
                return assembly_doc
            else:
                raise Exception("NewAssembly 返回空对象")
        except Exception as e:
            raise Exception(f"NewAssembly 失败: {e}")
    else:
        try:
            assembly_doc = sw_app.NewDocument(template_path, 0, 0, 0)
            if assembly_doc:
                print("✅ 使用模板成功创建装配体")
                # 等待装配体完全初始化
                time.sleep(1)
                return assembly_doc
            else:
                raise Exception("NewDocument 返回空对象")
        except Exception as e:
            raise Exception(f"NewDocument 失败: {e}")

    return  "创建完成"


def add_components_to_assembly(sw_app, assembly_model, part_paths):
    """
    向装配体中添加零件组件。

    :param sw_app: SolidWorks 应用程序对象
    :param assembly_model: 装配体模型 (IModelDoc2)
    :param part_paths: 零件路径列表
    """
    # 确保COM库初始化
    pythoncom.CoInitialize()
    
    # 获取装配体标题（安全方式）
    assembly_title = "默认装配体"
    try:
        temp_title = assembly_model.GetTitle
        if temp_title and isinstance(temp_title, str):
            assembly_title = temp_title
        print(f"当前装配体: {assembly_title}")
    except Exception as e: 
        print(f"⚠️ 获取装配体标题失败: {e}")
    error = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
    warnings=win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
    Part = sw_app.ActivateDoc3(assembly_title, True, 0,error)
    # 使用更直接的方式调用装配体方法，避免类型转换问题
    base_path = r"solidworksdata\一体式油水分离器"
    
    for part_name in part_paths:
        # 修复路径构建，去除可能的空格
        part_name = part_name.strip()  # 去除首尾空格
        part_path = f"{part_name}.sldprt"
        full_path = os.path.join(base_path, part_path)
        full_path = os.path.abspath(full_path)
        
        # 清理路径中的多余空格
        full_path = full_path.replace("\ ", " ").replace(" \\", "\\")
        
        if not os.path.exists(full_path):
            print(f"⚠️ 文件不存在: {full_path}")
            continue

        print(f"正在插入零件: {full_path}")
        # 打开文档
        part_doc = sw_app.OpenDoc6(
            full_path,  # 文件路径
            1,          # 文档类型 (1=零件)
            32,         # 打开选项 (32=Quiet打开，无用户界面)
            "",         # 配置名称
            error,     # 错误变量
            warnings    # 警告变量
        )
        try:
      
            # 使用更简单的方式直接插入组件，不预先打开零件
            component = Part.AddComponent5(
                full_path,      # CompName: 零件路径
                0,              # ConfigOption: 配置选项 (0=当前配置)
                "",             # NewConfigName: 新配置名称
                False,          # UseConfigForPartReferences: 是否使用配置作为参考
                "",             # ExistingConfigName: 现有配置名称
                0.0,            # X: X坐标
                0.0,            # Y: Y坐标
                0.0             # Z: Z坐标
            )
            sw_app.CloseDoc(full_path)
            if component:
                try:
                    comp_name = component.Name2
                except:
                    comp_name = os.path.basename(full_path)
                print(f"✅ 成功插入零件: {comp_name}")
            else:
                print(f"❌ 插入失败: {full_path}")
        except Exception as e:
            print(f"❌ 插入零件 {part_name} 时出错: {e}")
            
            # 如果 AddComponent5 失败，尝试使用更简单的方法
            try:
                print(f"  尝试使用 AddComponent2 方法...")
                component2 = assembly_model.AddComponent2(
                    full_path,
                    0,  # 默认对齐
                    0.0, 0.0, 0.0  # 位置
                )
                if component2:
                    print(f"  ✅ 使用 AddComponent2 成功插入零件: {part_name}")
                else:
                    print(f"  ❌ AddComponent2 也失败: {full_path}")
            except Exception as e2:
                print(f"  ❌ AddComponent2 方法也失败: {e2}")


def add_part(part_files):
    # 可选：指定模板路径，或设为 None 让程序尝试 NewAssembly
    template_path = r"C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2025\templates\gb_assembly.asmdot"

    # === 主逻辑 ===
    sw_app = get_sw_app()
    if not sw_app:
        print("❌ 请先启动 SolidWorks")
        return ("❌ 请先启动 SolidWorks")

    try:
        assembly_model = create_or_use_assembly(sw_app, template_path)
        if assembly_model:
            add_components_to_assembly(sw_app, assembly_model, part_files)
            print("🎉 所有零件处理完成！")
            return ("🎉 所有零件处理完成！")
        else:
            print("❌ 未能创建或获取装配体")
            return ("❌ 未能创建或获取装配体")
    except Exception as e:
        print(f"❌ 操作失败: {e}")


# =========================  
# 使用示例
# =========================
if __name__ == "__main__":
    # === 配置参数 ===
    part_files = [
        "电机",
        "主体1",
        # 添加更多零件...
    ]

    add_part([
        "电机",
        "主体1",
        # 添加更多零件...
    ]
)